/*
model for mcv format.
*/

#include "mvc/mycontroller.h"

// ----------------- constructors ---------------- //
MyController::MyController() {
    parent = 0;
}

MyController::MyController(MyController* new_parent) {
    parent = new_parent;
}

// --------------- getters/setters --------------- //
MyModel* MyController::getModel() {
    return model;
}
void MyController::setModel(MyModel* val) {
    model = val;
}

MyView* MyController::getView() {
    return view;
}
void MyController::setView(MyView* val) {
    view = val;
    view->setController(this);
}

MyController* MyController::getParent() {
    return parent;
}
void MyController::setParent(MyController* val) {
    parent = val;
}

// ------------------- other --------------------- //
void MyController::addChild(MyController* val) {
    view->addChild(val->getView());
    val->setParent(this);
    children.push_back(val);
}
void MyController::removeChild(MyController* val) {
    for(int i = 0; i < children.size(); i++) {
        if(children[i] == val) {
            children.erase(children.begin() + i);
            break;
        }
    }
}

void MyController::sendUpward(ALLEGRO_EVENT* ev) {
    // forward event up controller chain
    parent->processEvent(ev);
}

void MyController::hitTest(ALLEGRO_EVENT* ev) {
    bool inside;

    // check if event is inside self
    inside = insideMe(ev->mouse.x, ev->mouse.y);

    // take appropriate action
    if(inside) {
        for(int i = 0; i < children.size(); i++) {
            inside = false;

            // check if event is inside this child
            inside = children[i]->insideMe(ev->mouse.x, ev->mouse.y);

            // take appropriate action
            if(inside) {
                children[i]->hitTest(ev);
                break;
            }
        }
        // if the event travels no further down the view chain then:
        if(!inside) processEvent(ev);
    }
}

void MyController::killChildren() {
    for(int i = 0; i < children.size(); i++) {
        children[i]->kill();
    }
}

void MyController::kill() {
    killChildren();

    view->getParent()->removeChild(view);
    parent->removeChild(this);
    model->kill();

    delete this;
    delete view;
}

// ------------------ virtual -------------------- //
void MyController::processEvent(ALLEGRO_EVENT* ev) {
    
}

bool MyController::insideMe(int x, int y) {
    /*  insert code here to determine if event occured inside this
        controller's view */

    return false;
}

